package com.xiaotu.spider.project.pageprocessor.nettv;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.NetTVModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.HtmlUtil;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.spider.AUrlPageProcessor;

import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.selector.Html;

/**
 * 腾讯最新三年网剧爬取：名称、集数、类型、导演、主演、语言、年份、简介、播放量、评分
 *
 * @auther GaoHJ
 * @create 2017/10/11
 */
@Component("QQNetTVPageProcessor")
public class QQNetTVPageProcessor extends AUrlPageProcessor
{
    //private static final String[] YEARS = new String[]{"860-2015", "859-2016", "2017-2017"};
    private static final String BASE_URL = "http://v.qq.com/x/list/tv?offset=0&iarea=%s&iyear=%s";
    
    private static final String AREA_ID = "-1";//全部地区为-1，内地为814

    private static String [] YEARS = new String[3];//最近三年热播剧
	
	private static String one_url_0 = "860-";
	
	private static String two_url_0 = "859-";
	
	private static String three_url_0 = "2017-";
	
	static {
		String[] recentYears = DateUtils.getRecentYears(3);
		for(int i = 0;i<recentYears.length;i++){
			if(i==0){
				YEARS[i] = one_url_0+recentYears[i];
			}else if(i==1){
				YEARS[i] = two_url_0+recentYears[i];
			}else if(i==2){
				YEARS[i] = three_url_0+recentYears[i];
			}
		}
	}
    
    @Override
    public void process(Page page)
    {
        if (Constants.PageDataType.SEARCH_LIST.equals(this.getPageDataType(page)))
            this.listProcess(page);
        else
            pageProcess(page);
    }

    private void listProcess(Page page)
    {
        Html html = page.getHtml();
        List<String> divList = html.xpath("//ul[@class='figures_list']/li").all();
        if (divList == null || divList.isEmpty())
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);

        divList.forEach(divStr ->
        {
            Html divObj = new Html(divStr);
            String play = divObj.xpath("//span[@class='num']/text()").get();
            if (StringUtils.isEmpty(play))
                throw new SpiderException(SpiderExceptionCode.DataInvalideException);
            String score = StringUtils.join(divObj.xpath("//div[@class='figure_score']/em/text()" +
                    "").all(), StringUtils.EMPTY);
            String sets = divObj.xpath("//span[@class='figure_info']/text()").regex(RegexUtils
                    .REGEX_INTEGER).get();
            Map<String, Object> map = PageUtils.getNewExtraMapFromPage(page, new String[]{"play",
                    "score", "sets"}, new String[]{play, score, sets});
            PageUtils.addTargetRequest(page, divObj.xpath("//a[@class='figure']/@href").get(), map);
        });

        String url = html.xpath("//div[@class='mod_pages']//a[@class='page_next']/@href").get();
        if (StringUtils.isNotEmpty(url) && !url.contains("javascript"))
            PageUtils.addTargetRequest(page, url, page.getRequest().getExtras());

    }

    private void pageProcess(Page page)
    {
        Html html = page.getHtml();
        List<String> tagList = html.xpath("//div[@class='video_tags']//a[@_stat='intro:tag']/text" +
                "()").all();
        if (tagList == null || tagList.size() < 2)
            this.exceptionHandle(page);
        String title = html.xpath("//a[@class='_main_title']/text()").get();
        if (StringUtils.isEmpty(title))
            this.exceptionHandle(page);
        String[] figureArr = HtmlUtil.delHTMLTag(html.xpath("//div[@class='director']").get())
                .split("演员:");
        String director = this.getFormateFigure(figureArr[0].replace("导演:", StringUtils.EMPTY));
        String actor = this.getFormateFigure(figureArr[1]);
        String desc = html.xpath("//p[@class='summary']/text()").get();
        String play = html.xpath("//div[@class='action_item action_count']/a/span/em/text()").get();
        Map<String, Object> map = page.getRequest().getExtras();
        String sets ="";
        if(map.get("sets") == null){
        	List<String> setsList =html.xpath("//div[@class='video_info_wrap']//div[class='video_info']/div").all();
        	if(setsList !=null){
        		sets = HtmlUtil.delHTMLTag(setsList.get(1)).replaceAll("全", StringUtils.EMPTY).replaceAll("集", StringUtils.EMPTY);
        	}
        }else{
        	sets= StringUtil.nullToString(map.get("sets"));
        }
        String areas="";
        String years="";
        String divList = html.xpath("//div[@class='video_tags']").get();
        if(divList !=null && divList.contains("<span class=\"tag_item\">")){
        	List<String> areaList =html.xpath("//div[@class='video_tags _video_tags']/span").all();
        	if(areaList !=null){
        		if(areaList.size()>1){
        			areas =HtmlUtil.delHTMLTag(areaList.get(1));
        			years=tagList.get(0);
        		}else{
        			//字符串是否包含数字
        			if(isNumeric(areaList.get(0))){
        				years=HtmlUtil.delHTMLTag(areaList.get(0));
        				areas=tagList.get(0);
        			}else{
        				areas =HtmlUtil.delHTMLTag(areaList.get(0));
        				years=tagList.get(0);
        			}
        		}
        	}
        }else{
        	areas=tagList.get(0);
        	years=tagList.get(1);
        }
        page.putField(NetTVModel.class.getName(), new NetTVModel(Constants.TargetType
                .OTHER_TYPE_ID, title, Constants.SiteName.QQTV, sets, 
                tagList.size() > 2 ? StringUtils.join(tagList.subList(2, tagList.size
                ()), SepratorUtil.SEP_COMMA_EN) : StringUtils.EMPTY, null, areas,
                years, director, actor, desc, play, StringUtil.nullToString(map.get
                ("score")), StringUtil.nullToString(map.get("year"))));
    }

    private void exceptionHandle(Page page)
    {
        //        String title = StringUtils.trim(page.getHtml().xpath
        // ("//h1[@class='video_title']/text()")
        //                .get());
        //        FileUtil.writeFile("D://err.csv", title + SepratorUtil.SEP_PIPE + page.getUrl()
        // .toString
        //                () + SepratorUtil.LINE_SEPRATOR);
        throw new SpiderException(SpiderExceptionCode.DataInvalideException);
    }

    private String getFormateFigure(String figure)
    {
        if (StringUtils.isEmpty(figure))
            return StringUtils.EMPTY;
        return figure.replaceAll(" /  ", SepratorUtil.SEP_COMMA_EN).replaceAll("/ ", SepratorUtil
                .SEP_COMMA_EN).trim();
    }
    
    public boolean isNumeric(String str){ 
 	   Pattern pattern = Pattern.compile("[0-9]*"); 
 	   Matcher isNum = pattern.matcher(str);
 	   if( !isNum.matches() ){
 	       return false; 
 	   } 
 	   return true; 
 	}

    @Override
    protected List<JSONObject> getStartRequestUrlsAndParams()
    {
        List<JSONObject> list = new ArrayList<>();
        Stream.of(YEARS).forEach(year ->
        {
            String[] arr = year.split(SepratorUtil.SEP_CROSS_EN);
            JSONObject target = new JSONObject();
            target.put("year", arr[1]);
            target.put(URL_KEY, String.format(BASE_URL, AREA_ID, arr[0]));
            list.add(target);
        });
        return list;
    }

    @Override
    protected String[] getStartRequestUrls()
    {
        return null;
    }

    @Override
    protected String getSpiderType()
    {
        return "QQ_NetTV";
    }

    @Override
    public String getPageDataType(Page page)
    {
        if (page.getUrl().toString().contains("http://v.qq.com/x/list/tv"))
            return Constants.PageDataType.SEARCH_LIST;
        else
            return Constants.PageDataType.TV_RECORD;
    }
    
}
